package com.ubxtech.db.util;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ubxtech.core.exception.ErrorCode;
import com.ubxtech.core.exception.ErrorCodeCore;
import com.ubxtech.core.exception.RRException;

import jakarta.validation.constraints.NotNull;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

/**
 * 校验是否重复数据
 * @author Victor.Xiao
 * @since 2023-11-13 20:06
 **/
public class DataRepeatCheckUtil {


    /**
     * 可用于新增数据重名判断,只校验是否存在
     * @author Victor.Xiao
     * @since 2023-11-13 20:21
     * @param iService iService
     * @param checkColumnName checkColumnName
     * @param value value
     * @return boolean
     */
    public static <T> boolean checkRepeatAddData(@NotNull IService<T> iService,@NotNull String checkColumnName, @NotNull Serializable value) {
        return checkRepeatAddData(iService, checkColumnName, value, true,"");
    }

    /**
     * 可用于新增数据重名判断,只校验是否存在
     * @author Victor.Xiao
     * @since 2023-11-13 20:21
     * @param iService iService
     * @param checkColumnName checkColumnName
     * @param value value
     * @param throwMes 可以是字符串也可以是ErrorCode
     * @return boolean
     */
    public static <T> boolean checkRepeatAddData(IService<T> iService,String checkColumnName, Serializable value,boolean throwEx,Object throwMes) {
        List<String> checkColumnNames = new ArrayList<>();
        checkColumnNames.add(checkColumnName);
        List<Serializable> values = new ArrayList<>();
        values.add(value);
        return checkRepeatAddData(iService, checkColumnNames, values, throwEx,throwMes);
    }

    /**
     * 可用于新增数据重名判断,只校验是否存在
     * @author Victor.Xiao
     * @since 2023-11-13 20:21
     * @param iService iService
     * @param checkColumnNames checkColumnNames
     * @param values values
     * @param throwMes 可以是字符串也可以是ErrorCode
     * @return boolean
    */
    public static <T> boolean checkRepeatAddData(IService<T> iService, List<String> checkColumnNames, List<Serializable> values, boolean throwEx,Object throwMes) {
        if (CollectionUtil.isEmpty(checkColumnNames) || CollectionUtil.isEmpty(values) || checkColumnNames.size() != values.size() || iService == null) {
            throw new RRException(ErrorCodeCore.INTERNAL_SERVER_ERR);
        }
        QueryWrapper<T> queryWrapper = new QueryWrapper<>();
        for (int i = 0; i < checkColumnNames.size(); i++) {
            queryWrapper.eq(checkColumnNames.get(i), values.get(i));
        }
        queryWrapper.last("limit 1");
        T entity = iService.getOne(queryWrapper, false);
        if (entity != null) {
            if (throwEx) {
                if (throwMes == null) {
                    throwMes = "data repeat";
                }
                if (throwMes instanceof String) {
                    throw new RRException(throwMes.toString());
                }
                if (throwMes instanceof ErrorCode) {
                    ErrorCode errorCode = (ErrorCode) throwMes;
                    throw new RRException(errorCode);
                }
                throw new RRException(ErrorCodeCore.DUPLICATE_KEY_NAME);
            }
            return true;
        }
        return false;
    }

    /**
     * 可用于修改数据重名判断,只校验是否存在
     * @author Victor.Xiao
     * @since 2023-11-13 20:24
     * @param iService iService
     * @param checkColumnName checkColumnName
     * @param value value
     * @param id id
     * @return boolean
     */
    public static <T> boolean checkRepeatUpdateData(IService<T> iService,String checkColumnName, Serializable value,String idColumn,Serializable id){
        return checkRepeatUpdateData(iService, checkColumnName, value, idColumn, id, true,"");
    }


    /**
     * 可用于修改数据重名判断,只校验是否存在
     * @author Victor.Xiao
     * @since 2023-11-13 20:24
     * @param iService iService
     * @param checkColumnName checkColumnName
     * @param value value
     * @param id id
     * @param throwEx throwEx
     * @return boolean
     */
    public static  <T> boolean checkRepeatUpdateData(@NotNull IService<T> iService, @NotNull String checkColumnName, @NotNull Serializable value, @NotNull String idColumn, @NotNull Serializable id, boolean throwEx,String throwMes) {
        List<String> checkColumnNames = new ArrayList<>();
        checkColumnNames.add(checkColumnName);
        List<Serializable> values = new ArrayList<>();
        values.add(value);
        return checkRepeatUpdateData(iService, checkColumnNames, values, idColumn, id, throwEx, throwMes);
    }


    /**
     * 可用于修改数据重名判断,只校验是否存在
     * @author Victor.Xiao
     * @since 2023-11-13 20:24
     * @param iService iService
     * @param checkColumnName checkColumnName
     * @param value value
     * @param id id
     * @param throwEx throwEx
     * @return boolean
    */
    public static  <T> boolean checkRepeatUpdateData(@NotNull IService<T> iService,List<String> checkColumnName, List<Serializable> value, @NotNull String idColumn, @NotNull Serializable id, boolean throwEx,String throwMes) {
        if (CollectionUtil.isEmpty(checkColumnName) || CollectionUtil.isEmpty(value) || checkColumnName.size() != value.size()  || iService == null) {
            throw new RRException(ErrorCodeCore.INTERNAL_SERVER_ERR);
        }
        if (StrUtil.isBlank(idColumn) || id == null || StrUtil.isBlank(id.toString())) {
            throw new RRException(ErrorCodeCore.INTERNAL_SERVER_ERR);
        }
        QueryWrapper<T> queryWrapper = new QueryWrapper<>();
        for (int i = 0; i < checkColumnName.size(); i++) {
            queryWrapper.eq(checkColumnName.get(i), value.get(i));
        }
        queryWrapper.ne(idColumn, id);
        queryWrapper.last("limit 1");
        T entity = iService.getOne(queryWrapper, false);
        if (entity != null) {
            if (throwEx) {
                if (StrUtil.isNotBlank(throwMes)) {
                    throw new RRException(throwMes);
                }
                throw new RRException(ErrorCodeCore.DUPLICATE_KEY_NAME);
            }
            return true;
        }
        return false;
    }
}
